package com.baizhi.cmfzmanager.lucene.impl;

import com.baizhi.cmfzmanager.dao.ArticleDao;
import com.baizhi.cmfzmanager.entity.Article;
import com.baizhi.cmfzmanager.entity.ArticleDTO;
import com.baizhi.cmfzmanager.lucene.LuceneService;
import com.baizhi.cmfzmanager.util.LuceneUtil;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class LuceneServiceImpl implements LuceneService {
    @Autowired
    private ArticleDao articleDao;

    @Override
    public int addIndexs(List<Article> articles) {
        List<Document> documents=new ArrayList<>();
        for (Article article : articles) {
            Document document = LuceneUtil.addArticle(article);
            documents.add(document);
        }

        IndexWriter indexWriter = LuceneUtil.getIndexWriter();
        try {
            indexWriter.addDocuments(documents);
        } catch (IOException e) {
            e.printStackTrace();
            return 1;
        }finally {
            LuceneUtil.commit(indexWriter);
        }

        return 0;
    }

    @Override
    public boolean addIndexOne(Article article) {
        Document document = LuceneUtil.addArticle(article);
        IndexWriter indexWriter = LuceneUtil.getIndexWriter();
        try {
            indexWriter.addDocument(document);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally {
            LuceneUtil.commit(indexWriter);
        }
        return true;
    }

    @Override
    public boolean deleteAllIndex() {
        IndexWriter indexWriter = LuceneUtil.getIndexWriter();
        try {
            indexWriter.deleteAll();
        } catch (IOException e) {
            e.printStackTrace();
            return  false;
        }finally {
            LuceneUtil.commit(indexWriter);
        }

        return true;
    }

    @Override
    public boolean deleteOne(Article article) {
        IndexWriter indexWriter = LuceneUtil.getIndexWriter();
        try {
            indexWriter.deleteDocuments(new Term("articleId",article.getArticleId().toString()));
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally {
            LuceneUtil.commit(indexWriter);
        }
        return true;
    }

    @Override
    public boolean updateOne(Article article) {
        Document document = LuceneUtil.addArticle(article);
        IndexWriter indexWriter = LuceneUtil.getIndexWriter();
        Term term = new Term("articleId",article.getArticleId().toString());
        try {
            indexWriter.updateDocument(term,document);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally {
            LuceneUtil.commit(indexWriter);
        }
        return true;
    }

    @Override
    public List<Article> queryByKeyword(String keyword) {
        Query query = LuceneUtil.getQuery(keyword);
        IndexSearcher indexSearch = LuceneUtil.getIndexSearch();
        List<Article> articles=new ArrayList<>();
        QueryScorer queryScorer=new QueryScorer(query);
        SimpleHTMLFormatter simpleHTMLFormatter=new SimpleHTMLFormatter("<font color='red'>","</font>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter,queryScorer);
        try {
            TopDocs search = indexSearch.search(query, 100);
            ScoreDoc[] scoreDocs = search.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {
                int docID = scoreDoc.doc;
                Document document = indexSearch.doc(docID);
                String articleId = document.get("articleId");
                String articleName = document.get("articleName");
                String articleImage = document.get("articleImage");
                String articleContext = document.get("articleContext");
                articleName = highlighter.getBestFragment(LuceneUtil.analyzer, "articleName", articleName);
                articleContext = highlighter.getBestFragment(LuceneUtil.analyzer, "articleContext", articleContext);
                Article article=new Article();
                article.setArticleId(Integer.parseInt(articleId));
                article.setArticleName(articleName);
                article.setArticleImage(articleImage);
                article.setArticleContent(articleContext);
                articles.add(article);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidTokenOffsetsException e) {
            e.printStackTrace();
        }

        return articles;
    }

    @Override
    public boolean resetIndexDB() {
        try {
            deleteAllIndex();
            List<Article> articles = articleDao.selectList(null);
            addIndexs(articles);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
